package com.inkFlow.crawl.core.template.text;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.inkFlow.book.domain.InkBook;
import com.inkFlow.book.domain.InkBookChapter;
import com.inkFlow.book.mapper.InkBookChapterMapper;
import com.inkFlow.book.mapper.InkBookMapper;
import com.inkFlow.common.core.constant.CrawlConstants;
import com.inkFlow.common.core.constant.CrawlDBConstants;
import com.inkFlow.common.core.domain.model.LoginUser;
import com.inkFlow.common.core.utils.SpringUtils;
import com.inkFlow.common.core.utils.StringUtils;
//import com.inkFlow.crawl1.model.CrawlSourceConfigExtTextRule;
import com.inkFlow.crawl.core.template.SimpleEntity;
import com.inkFlow.crawl.core.util.AnalyzeRuleUtil;
import com.inkFlow.crawl.domain.CrawlSourceConfigExtTextRule;
import com.inkFlow.crawl.mapper.CrawlSourceConfigExtTextRuleMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Request;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.processor.PageProcessor;
import us.codecraft.webmagic.selector.Html;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Description: 小说页面通用处理
 * @author: inkFlow
 * @date: 2025-08-14 10:09:17
 **/
@Slf4j
public class SimpleTextPageProcessor implements PageProcessor {

    private final Site site;
    private final CrawlSourceConfigExtTextRule textRule;
    private final InkBookMapper inkBookMapper;
    private final LoginUser loginUser;
    private final InkBookChapterMapper inkBookChapterMapper;

    public SimpleTextPageProcessor(Site site, CrawlSourceConfigExtTextRule textRule, LoginUser loginUser) {
        this.site = site;
        this.textRule = textRule;
        this.loginUser = loginUser;
        this.inkBookMapper = SpringUtils.getBean(InkBookMapper.class);
        this.inkBookChapterMapper = SpringUtils.getBean(InkBookChapterMapper.class);
    }

    @Override
    public void process(Page page) {
        // 判断当前页面的类型
        Map<String, Object> extras = page.getRequest().getExtras();
        String processorLevel = extras.get(CrawlConstants.PROCESSOR_LEVEL_KEY).toString();
        SimpleEntity simpleEntity = (SimpleEntity) extras.get(CrawlConstants.SIMPLE_ENTITY_KEY);
        switch (processorLevel) {
            // 分类页面
            case CrawlConstants.PROCESSOR_LEVEL_VALUE_CATEGORY_PAGE:
                this.parseCategorPage(page, simpleEntity);
                break;
            // 详情页面
            case CrawlConstants.PROCESSOR_LEVEL_VALUE_INFO_PAGE:
                this.parseInfoPage(page, simpleEntity);
                break;
            // 目录页面
            case CrawlConstants.PROCESSOR_LEVEL_VALUE_TOC_PAGE:
                this.parseTocPage(page);
                break;
            // 正文页面
            case CrawlConstants.PROCESSOR_LEVEL_VALUE_CONTENT_PAGE:
                this.parseContentPage(page,simpleEntity);
                break;
            default:
                break;
        }
    }

    @Override
    public Site getSite() {
        return this.site;
    }

    /**
     * 解析分类页面
     *
     * @param page
     */
    private void parseCategorPage(Page page, SimpleEntity simpleEntity) {
        // 分类页面小说的id
        String categoryBookIdRule = textRule.getCategoryBookIdRule();
        List<String> categoryBookIdList = AnalyzeRuleUtil.analyzeAll(page, categoryBookIdRule);
        // 小说的名称
        String categoryBookNameRule = textRule.getCategoryBookNameRule();
        List<String> categoryBookNameList = AnalyzeRuleUtil.analyzeAll(page, categoryBookNameRule);
        // 小说的具体地址
        String categoryBookUrlRule = textRule.getCategoryBookUrlRule();
        List<String> categoryBookUrlList = AnalyzeRuleUtil.analyzeAllLinks(page, categoryBookUrlRule);
        // 有的小说地址是短链接 可能需要拼全
        String bookJoinurl = textRule.getCategoryBookJoinUrl();
        if (StringUtils.isNotEmpty(bookJoinurl)) {
            categoryBookUrlList = categoryBookUrlList.stream().map(url -> {
                if (url.startsWith("http") || url.startsWith("https")) {
                    return url;
                } else if (url.startsWith("/")) {
                    return bookJoinurl + url.substring(1);
                }
                return bookJoinurl + url;
            }).collect(Collectors.toList());
        }
        // 获取当前分类总页数
        String categoryTotalPageRule = textRule.getCategoryTotalPageRule();
        String categoryTotalPage = AnalyzeRuleUtil.analyzeOne(page, categoryTotalPageRule);
        if (StringUtils.isNotEmpty(categoryTotalPage)) {
            simpleEntity.setCategoryPageTotal(Integer.valueOf(categoryTotalPage));
        }
        if (CollectionUtils.isEmpty(categoryBookUrlList) || CollectionUtils.isEmpty(categoryBookIdList) || CollectionUtils.isEmpty(categoryBookNameList)) {
            return;
        }
        List<InkBook> categoryBookInfoList = new ArrayList<>();
        //for (int i = 0; i < categoryBookUrlList.size(); i++) {
        for (int i = 0; i < 1; i++) {
            Integer crawlId = textRule.getCrawlId();
            String crawlBookUrl = categoryBookUrlList.get(i);
            String crawlBookId = categoryBookIdList.get(i);
            String crawlBookName = categoryBookNameList.get(i);
            // 查询数据库是否存在
            InkBook bookInfo = inkBookMapper.selectOne(new LambdaQueryWrapper<InkBook>()
                .eq(InkBook::getCrawlSourceId, crawlId)
                .eq(InkBook::getCrawlBookId, crawlBookId));
            // TODO: 已存在的就不继续往下走了 走定时任务去更新这写书
            // 存储
            InkBook newBook = new InkBook();
            newBook.setBookName(crawlBookName);
            newBook.setCrawlSourceId(crawlId);
            newBook.setCrawlBookId(crawlBookId);
            newBook.setBookSource(CrawlDBConstants.INK_BOOK_BOOK_SOURCE_2);
            newBook.setVipStatus(CrawlDBConstants.INK_BOOK_VIP_STATUS_1);
            newBook.setCreateDept(loginUser.getDeptId());
            newBook.setCreateBy(loginUser.getUserId());
            if (Objects.nonNull(bookInfo)) {
                newBook.setBookId(bookInfo.getBookId());
            }
            categoryBookInfoList.add(newBook);
            // 请求小说详情页面
            Request request = new Request(crawlBookUrl);
            Map<String, Object> extraMap = new HashMap<>();
            // 详情页面
            extraMap.put(CrawlConstants.PROCESSOR_LEVEL_KEY, CrawlConstants.PROCESSOR_LEVEL_VALUE_INFO_PAGE);
            simpleEntity.setInfoPageIndex(1);
            simpleEntity.setCrawlBookId(crawlBookId);
            extraMap.put(CrawlConstants.SIMPLE_ENTITY_KEY, simpleEntity);
            request.setExtras(extraMap);
            page.addTargetRequest(request);
        }
        // 保存分类小说信息
        if (!CollectionUtils.isEmpty(categoryBookInfoList)) {
            page.putField("categoryBookInfoList", categoryBookInfoList);
            page.putField(CrawlConstants.PIPELINE_LEVEL_KEY, CrawlConstants.PIPELINE_LEVEL_VAULE_CATEGORY_PAGE);
        }

    }

    /**
     * 解析详情页面-解析小说详情，在详情中去加载目录页面
     *
     * @param page
     */
    private void parseInfoPage(Page page, SimpleEntity simpleEntity) {
        // 先查询出来小说
        String crawlBookId = simpleEntity.getCrawlBookId();
        Integer crawlId = simpleEntity.getCrawlId();
        InkBook bookInfo = inkBookMapper.selectOne(new LambdaQueryWrapper<InkBook>()
            .eq(InkBook::getCrawlSourceId, crawlId)
            .eq(InkBook::getCrawlBookId, crawlBookId));
        if (Objects.isNull(bookInfo)) {
            log.info("根据crawlId：{}，crawlBookId：{}，查询小说为null", crawlId, crawlBookId);
            return;
        }
        Integer bookId = bookInfo.getBookId();
        InkBook updateBookInfo = new InkBook();
        updateBookInfo.setBookId(bookId);
        // 先获取作者
        String bookInfoAuthorRule = textRule.getBookInfoAuthorRule();
        String bookInfoAuthor = AnalyzeRuleUtil.analyzeOne(page, bookInfoAuthorRule);
        updateBookInfo.setAuthorName(bookInfoAuthor);
        // 封面
        String bookInfoCoverRule = textRule.getBookInfoCoverRule();
        String bookInfoCover = AnalyzeRuleUtil.analyzeOne(page, bookInfoCoverRule);
        updateBookInfo.setCoverUrl(bookInfoCover);
        // 小说简介
        String bookInfoIntroRule = textRule.getBookInfoIntroRule();
        String bookInfoIntro = AnalyzeRuleUtil.analyzeOne(page, bookInfoIntroRule);
        updateBookInfo.setBookDesc(bookInfoIntro);
        // 保存小说详情 多线程环境直接获取user 会报错
        updateBookInfo.setUpdateBy(loginUser.getUserId());
        page.putField("bookInfo", updateBookInfo);
        page.putField(CrawlConstants.PIPELINE_LEVEL_KEY, CrawlConstants.PIPELINE_LEVEL_VAULE_INFO_PAGE);

        // 是否存在目录规则
        String bookTocUrlRule = textRule.getBookTocUrlRule();
        if (StringUtils.isNoneBlank(bookTocUrlRule)) {
            // 存在的话跳转到目录规则页面
            String bookTocChapterUrl = bookTocUrlRule.replace("", "");
            return;
        }
        // 获取详情章节id list
        String bookChapterIdRule = textRule.getBookChapterIdRule();
        List<String> bookChapterIdList = AnalyzeRuleUtil.analyzeAll(page, bookChapterIdRule);
        // 获取详情章节name list
        String bookChapterNameRule = textRule.getBookChapterNameRule();
        List<String> bookChapterNameList = AnalyzeRuleUtil.analyzeAll(page, bookChapterNameRule);
        // 获取详情章节url list
        String bookChapterUrlRule = textRule.getBookChapterUrlRule();
        List<String> bookChapterUrlList = AnalyzeRuleUtil.analyzeAllLinks(page, bookChapterUrlRule);
        if (CollectionUtils.isEmpty(bookChapterIdList) || CollectionUtils.isEmpty(bookChapterNameList) || CollectionUtils.isEmpty(bookChapterUrlList)) {
            return;
        }
        List<InkBookChapter> inkBookChapterList = new ArrayList<>();
        // 章节列表
        //for (int i = 0; i < bookChapterIdList.size(); i++) {
        for (int i = 0; i < 1; i++) {
            String bookChapterUrl = bookChapterUrlList.get(i);
            String crawlChapterId = bookChapterIdList.get(i);
            String bookChapterName = bookChapterNameList.get(i);
            // 查询是否存在该章节了
            InkBookChapter inkBookChapter = inkBookChapterMapper.selectOne(new LambdaQueryWrapper<InkBookChapter>()
                .eq(InkBookChapter::getBookId, bookId)
                .eq(InkBookChapter::getCrawlChapterId,crawlChapterId));
            // TODO: 已存在的就不继续往下走了 走定时任务去更新这写书
            InkBookChapter newBookChapter = new InkBookChapter();
            newBookChapter.setBookId(bookId);
            newBookChapter.setChapterName(bookChapterName);
            newBookChapter.setCrawlChapterId(crawlChapterId);
            newBookChapter.setVipStatus(CrawlDBConstants.INK_BOOK_CHAPTER_VIP_STATUS_1);
            if (Objects.nonNull(inkBookChapter)) {
                newBookChapter.setChapterId(inkBookChapter.getChapterId());
            }
            inkBookChapterList.add(newBookChapter);
            // 请求章节具体内容
            // 请求小说详情页面
            Request request = new Request(bookChapterUrl);
            Map<String, Object> extraMap = new HashMap<>();
            // 详情页面
            extraMap.put(CrawlConstants.PROCESSOR_LEVEL_KEY, CrawlConstants.PROCESSOR_LEVEL_VALUE_CONTENT_PAGE);
            simpleEntity.setCrawlBookChapterId(crawlChapterId);
            simpleEntity.setBookId(bookId);
            simpleEntity.setContentPageIndex(1);
            simpleEntity.setCrawlBookId(crawlBookId);
            extraMap.put(CrawlConstants.SIMPLE_ENTITY_KEY, simpleEntity);
            request.setExtras(extraMap);
            page.addTargetRequest(request);
        }
        // 保存小说章节信息
        if (!CollectionUtils.isEmpty(inkBookChapterList)) {
            page.putField("inkBookChapterList", inkBookChapterList);
            page.putField(CrawlConstants.PIPELINE_LEVEL_KEY, CrawlConstants.PIPELINE_LEVEL_VAULE_INFO_PAGE);
        }
    }

    /**
     * 解析目录页面
     *
     * @param page
     */
    private void parseTocPage(Page page) {

    }

    /**
     * 解析正文页面
     *
     * @param page
     */
    private void parseContentPage(Page page,SimpleEntity simpleEntity ) {
        // 先查询出来小说章节
        String crawlChapterId = simpleEntity.getCrawlBookChapterId();
        Integer bookId = simpleEntity.getBookId();
        InkBookChapter inkBookChapter = inkBookChapterMapper.selectOne(new LambdaQueryWrapper<InkBookChapter>()
            .eq(InkBookChapter::getBookId, bookId)
            .eq(InkBookChapter::getCrawlChapterId, crawlChapterId));
        if (Objects.isNull(inkBookChapter)) {
            log.info("根据bookId：{}，crawlChapterId：{}，查询小说章节为null", bookId, crawlChapterId);
            return;
        }
        InkBookChapter updateBookChapter = new InkBookChapter();
        updateBookChapter.setChapterId(inkBookChapter.getChapterId());
        // 先获取作者
        String bookContentRule = textRule.getBookContentRule();
        String bookContent = AnalyzeRuleUtil.analyzeOne(page, bookContentRule);
        String bookContentReplace = textRule.getBookContentReplace();
        bookContent = AnalyzeRuleUtil.replace(bookContent, bookContentReplace);
        updateBookChapter.setChapterContent(bookContent);
        if (StringUtils.isNoneBlank(bookContent)) {
            updateBookChapter.setWordCount(bookContent.length());
        }
        // 保存小说章节信息
        page.putField("updateBookChapter", updateBookChapter);
        page.putField(CrawlConstants.PIPELINE_LEVEL_KEY, CrawlConstants.PIPELINE_LEVEL_VAULE_CONTENT_PAGE);
    }
}













